/*
 * Copyright 2002-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.stereotype;

import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.config.ContextNamespaceHandler;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.w3c.dom.Element;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Component 派生性(等同于注解的继承)：凡是被Component元注解标注的都会被扫描。
 * 		     -但是从语法上面讲注解式没有继承的，所以称之为Component 派生性
 *
 *
 * Service、Repository、Controller称为模式注解。
 * Spring的模式注解：Stereotype Annotations
 *
 * http://ifeve.com/annotation-programming-model/
 *
 *
 * Stereotype模式注解
 *
 *
 * Stereotype注解是一种在应用中，常被用于声明要扮演某种职责或者角色的注解。
 * 		例如，@Repository注解用于标注任何履行了repository职责角色的类（这种职责角色通常也会被称为Data Access Object或者DAO）。
 *
 *  {@link Component @Component} 是被Spring管理的组件的对应注解。
 *  	任何标注了@Component的组件都会在spring组件扫描时被扫描到。
 *  	同样的，任何标注了 被元注解@Component标注过的注解 的组件，
 *  	也会在Spring组件扫描时被扫描到。例如，@Service就是一种被元注解@Component标注过的注解。
 *
 *  Spring核心框架提供了一系列可直接使用的stereotype注解，
 *  	包括但不限于@Component, @Service, @Repository, @Controller, @RestController, @Configuration。
 *  	, @Repository, @Service等等注解都基于@Component的更精细化的组件注解。
 *
 *
 *
 *
 *
 * Indicates that an annotated class is a "component".
 * Such classes are considered as candidates for auto-detection
 * when using annotation-based configuration and classpath scanning.
 *
 * 指示带注释的类是“组件”。
 * 当使用基于注释的配置和类路径扫描时，这些类被认为是自动检测的候选类。
 *
 * <p>Other class-level annotations may be considered as identifying
 * a component as well, typically a special kind of component:
 * e.g. the {@link Repository @Repository} annotation or AspectJ's
 * {@link org.aspectj.lang.annotation.Aspect @Aspect} annotation.
 *
 * 其他类级别的注释也可以被认为是标识组件，通常是一种特殊类型的组件:
 *
 * @author Mark Fisher
 * @since 2.5
 *
 * @see Repository：存储，实现数据库DAO层访问，持久层
 * @see Service：   服务，标记注入dao组件等，服务层
 * @see Controller：控制器，控制层，注入服务。
 * @see org.springframework.context.annotation.Configuration 配置类
 *
 * @see org.springframework.context.annotation.ComponentScan
 *
 * spring-context包下：spring.handlers
 * @see ContextNamespaceHandler#init()
 * @see org.springframework.context.annotation.ComponentScanBeanDefinitionParser#parse(Element, ParserContext)
 *
 * @see org.springframework.context.annotation.ClassPathBeanDefinitionScanner#ClassPathBeanDefinitionScanner(BeanDefinitionRegistry, boolean, Environment, ResourceLoader)
 * @see org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan(String...)
 * @see ClassPathScanningCandidateComponentProvider#registerDefaultFilters()
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {

	/**
	 * The value may indicate a suggestion for a logical component name,
	 * to be turned into a Spring bean in case of an autodetected component.
	 * @return the suggested component name, if any (or empty String otherwise)
	 */
	String value() default "";

}
